﻿using Bnbjoy.Business.Abstract;
using Bnbjoy.Business.Common;
using Bnbjoy.Business.Concrete;
using Bnbjoy.Business.Constants;
using Bnbjoy.Business.Model;
using Bnbjoy.Business.Model.Account;
using Bnbjoy.Domain.Abstract;
using Bnbjoy.Domain.Concrete;
using Bnbjoy.Domain.Entities;
using BnbjoyBackend.Api.Security;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace BnbjoyBackend.Api.Controllers
{
    [Authorize]
    public class AccountController : ApiController
    {
        [Route("api/account/register")]
        [HttpPost]
        public async Task<HttpPostResponse> Register([FromBody]UserRegistrationParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            //短信验证码比较
            using (IMobileCaptchaService mobileCaptchaService = new MobileCaptchaService(new MobileCaptchaRepository()))
            {
                bool vCodeMatch = await mobileCaptchaService.VerifyMobileCaptcha(param.MobileNumber, param.MobileCaptcha);
                if (!vCodeMatch)
                    return new HttpPostResponse(HttpStatusCode.BadRequest, "手机验证码不匹配");
            }

            int roleId = -1;
            switch (param.RoleName)
            {
                case "BA": roleId = 2; break;
                case "BE": roleId = 3; break;
                case "EU": roleId = 4; break;
            }

            if (roleId == -1)
                return new HttpPostResponse(HttpStatusCode.BadRequest, "无此用户角色");

            string profileId = Guid.NewGuid().ToString("n");

            var user = new User
            {
                UId = Guid.NewGuid().ToString("n"),
                RoleId = roleId,
                UserName = param.UserName,
                Password = SecurityManager.Instance.Md5AndBase64Encrypt(param.Password),
                Enabled = true,
                Email = param.Email,
                Mobile = param.MobileNumber,
                OwnerId = null,
                ProfileId = profileId,
                Approved = false,
                ApprovedTime = null,
                CreatedTime = DateTime.Now,
                LastLogin = DateTime.Now,
            };

            var profile = new Profile
            {
                UserId = user.UId,
                ProfileId = profileId,
            };

            using (IAccountService accountService = new AccountService<IUserRepository>(new UserRepository()))
            {
                var existedMobileUser = await accountService.FindUser(param.MobileNumber);
                if (existedMobileUser != null)
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "此手机号已被注册");

                var existedEmailUser = await accountService.FindUserByEmail(param.Email);
                if (existedEmailUser != null)
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "此邮箱已被注册");

                bool result = await accountService.AddUser(user, profile);
                if (result)
                {
                    //注册成功才移除验证码记录
                    using (IMobileCaptchaService mobileCaptchaService = new MobileCaptchaService(new MobileCaptchaRepository()))
                    {
                        await mobileCaptchaService.RemoveMobileCaptcha(param.MobileNumber);
                    }
                    return new HttpPostResponse(HttpStatusCode.OK, "注册成功");
                }
                else
                {
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "此用户名已被注册");
                }
            }
        }

        [Route("api/account/new_employee")]
        [HttpPost]
        [Authorize(Roles = "BA")]
        public async Task<HttpPostResponse> CreateEmployee([FromBody]NewEmployeeParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            int roleId = -1;
            switch (param.RoleName)
            {
                case "BA": roleId = 2; break;
                case "BE": roleId = 3; break;
                case "EU": roleId = 4; break;
            }

            if (roleId == -1)
                return new HttpPostResponse(HttpStatusCode.BadRequest, "无此用户角色");

            string profileId = Guid.NewGuid().ToString("n");

            var user = new User
            {
                UId = Guid.NewGuid().ToString("n"),
                RoleId = roleId,
                UserName = param.UserName,
                Password = SecurityManager.Instance.Md5AndBase64Encrypt(param.Password),
                Enabled = true,
                Email = param.Email,
                Mobile = param.Mobile,
                OwnerId = param.OwnerId,
                ProfileId = profileId,
                Approved = false, //当employee验证完手机之后，approve状态才会更改为true
                ApprovedTime = null,
                CreatedTime = DateTime.Now,
                LastLogin = DateTime.Now,
            };

            var profile = new Profile
            {
                UserId = user.UId,
                ProfileId = profileId,
                RealName = param.RealName,
            };

            using (IAccountService accountService = new AccountService<IUserRepository>(new UserRepository()))
            {
                var existedMobileUser = await accountService.FindUser(param.Mobile);
                if (existedMobileUser != null)
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "此手机号已被注册");

                var existedEmailUser = await accountService.FindUserByEmail(param.Email);
                if (existedEmailUser != null)
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "此邮箱已被注册");

                bool result = await accountService.AddUser(user, profile);
                if (result)
                {
                    dynamic backToClient = new ExpandoObject();
                    backToClient.employeeid = user.UId;
                    string backJson = JsonConvert.SerializeObject(backToClient);
                    return new HttpPostResponse(HttpStatusCode.OK, backJson);
                }
                else
                {
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "此用户名已被注册");
                }
            }
        }

        [Route("api/account/managedbnbs")]
        [HttpPost]
        [Authorize(Roles = "BA,BE")]
        public async Task<HttpPostResponse> ManagedBnbs()
        {
            if (User.Identity.IsAuthenticated)
            {
                string userName = User.Identity.Name;
                using (IAccountService accountService = new AccountService<IUserRepository>(new UserRepository()))
                {
                    IEnumerable<dynamic> bnbs = null;
                    //如果是BA，则得到BA创建的Bnb。如果是BE，则得到BE可管理的Bnb
                    if (User.IsInRole("BA"))
                        bnbs = await accountService.FetchBA_Bnbs(userName);
                    else if (User.IsInRole("BE"))
                        bnbs = await accountService.FetchBE_Bnbs(userName);

                    string infoJsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(bnbs);
                    return new HttpPostResponse(HttpStatusCode.OK, infoJsonStr);
                }
            }
            else
            {
                return new HttpPostResponse(HttpStatusCode.Forbidden, "访问被拒绝！");
            }
        }


        [Route("api/account/user_with_bnbpermission_info")]
        [HttpPost]
        [Authorize(Roles = "BA,BE")]
        public async Task<HttpPostResponse> UserWithBnbPermissionInfo([FromBody]UserAndBnbPermissionParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            try
            {
                if (User.Identity.IsAuthenticated)
                {
                    string userName = User.Identity.Name;
                    using (IAccountService accountService = new AccountService<IUserRepository>(new UserRepository()))
                    {
                        var userInfo = await accountService.ReadUserAndPermission(param.UserId, param.Role, param.BnbId);
                        var userInfoJson = JsonConvert.SerializeObject(userInfo);
                        UserAndBnbPermissionResponse response = JsonConvert.DeserializeObject<UserAndBnbPermissionResponse>(userInfoJson);
                        dynamic info = new ExpandoObject();
                        info.userId = response.UserId;
                        info.userName = response.UserName;
                        info.roleName = response.RoleName;
                        info.profileId = response.ProfileId;
                        info.permission = response.Permission;
                        info.bnbId = response.BnbId;
                        string infoJsonStr = JsonConvert.SerializeObject(info);
                        return new HttpPostResponse(HttpStatusCode.OK, infoJsonStr);
                    }
                }
                else
                {
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "访问被拒绝！");
                }
            }
            catch (Exception ex)
            {
                return new HttpPostResponse(HttpStatusCode.InternalServerError, "服务请求异常！");
            }
        }

        [Route("api/account/userinfo")]
        [HttpPost]
        [Authorize(Roles = "BA,BE")]
        public async Task<HttpPostResponse> UserInfo()
        {
            if (User.Identity.IsAuthenticated)
            {
                string userName = User.Identity.Name;
                using (IAccountService accountService = new AccountService<IUserRepository>(new UserRepository()))
                {
                    var userInfo = await accountService.ReadUserInfo(userName);
                    dynamic info = new ExpandoObject();
                    info.userId = userInfo.UId;
                    info.userName = userInfo.UserName;
                    info.roleName = Enum.GetName(typeof(RoleTypes), userInfo.RoleId);
                    info.profileId = userInfo.ProfileId;
                    string infoJsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(info);
                    return new HttpPostResponse(HttpStatusCode.OK, infoJsonStr);
                }
            }
            else
            {
                return new HttpPostResponse(HttpStatusCode.Forbidden, "访问被拒绝！");
            }
        }

        [Route("api/account/ownerandemployees")]
        [HttpPost]
        [Authorize(Roles = "BA")]
        public async Task<HttpPostResponse> UserAndEmployees()
        {
            if (User.Identity.IsAuthenticated)
            {
                //如果是民宿管理员
                if (User.IsInRole("BA"))
                {
                    string userName = User.Identity.Name;
                    using (IAccountService accountService = new AccountService<IUserRepository>(new UserRepository()))
                    {
                        //读取BA的详细信息
                        OwnerAndEmployeeModel ownerDetailInfo = await accountService.ReadUserDetailInfo(userName);

                        //根据uid得到对应的employees列表信息
                        IEnumerable<EmployeeModel> employees = await accountService.ReadRelatedEmployeesInfo(ownerDetailInfo.OwnerId);
                        ownerDetailInfo.Employees = employees;

                        string resultJson = JsonHelper.ConvertObjectToJson(ownerDetailInfo);
                        return new HttpPostResponse(HttpStatusCode.OK, resultJson);
                    }
                }
                else
                {
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "访问被拒绝！");
                }
            }
            else
            {
                return new HttpPostResponse(HttpStatusCode.Forbidden, "访问被拒绝！");
            }
        }

        [Route("api/account/change_employee_permissions")]
        [HttpPost]
        [Authorize(Roles = "BA")]
        public async Task<HttpPostResponse> ChangeEmployeePermission(ChangeEmployeePermissionParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            if (User.Identity.IsAuthenticated)
            {
                try
                {
                    using (IAccountService accountService = new AccountService<IUserRepository>(new UserRepository()))
                    {
                        bool success = await accountService.ChangePermission(param.UserId, param.BnbId, param.PermissionStr);
                        if (success)
                            return new HttpPostResponse(HttpStatusCode.OK, "权限修改成功！");
                        else
                            return new HttpPostResponse(HttpStatusCode.BadRequest, "新旧权限一致，修改无效！");
                    }
                }
                catch (Exception ex)
                {
                    return new HttpPostResponse(HttpStatusCode.InternalServerError, "权限修改异常！");
                }
            }
            else
            {
                return new HttpPostResponse(HttpStatusCode.Forbidden, "访问被拒绝！");
            }
        }

        [Route("api/account/employee_bnb_permissions")]
        [HttpPost]
        [Authorize(Roles = "BA")]
        public async Task<HttpPostResponse> EmployeeBnbPermissions(EmployeeBnbPermissionRequestParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            if (User.Identity.IsAuthenticated)
            {
                try
                {
                    using (IAccountService accountService = new AccountService<IUserRepository>(new UserRepository()))
                    {
                        IEnumerable<EmployeeBnbPermissionModel> list = await accountService.ReadEmployeeBnbPermissionList(param.UserId);
                        string result = JsonHelper.ConvertObjectToJson(list);
                        return new HttpPostResponse(HttpStatusCode.OK, result);
                    }
                }
                catch (Exception ex)
                {
                    return new HttpPostResponse(HttpStatusCode.InternalServerError, "获取权限列表失败！");
                }
            }
            else
            {
                return new HttpPostResponse(HttpStatusCode.Forbidden, "访问被拒绝！");
            }
        }

        [Route("api/account/add_remove_bnb_permission")]
        [HttpPost]
        [Authorize(Roles = "BA")]
        public async Task<HttpPostResponse> AddRemoveBnbPermission(AddRemoveBnbPermissionParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            if (User.Identity.IsAuthenticated)
            {
                try
                {
                    using (IAccountService accountService = new AccountService<IUserRepository>(new UserRepository()))
                    {
                        IEnumerable<dynamic> result = await accountService.AddRemoveBnbPermission(param);

                        if (result != null)
                        {
                            string resultJson = JsonHelper.ConvertObjectToJson(result);
                            return new HttpPostResponse(HttpStatusCode.OK, resultJson);
                        }
                        else
                        {
                            return new HttpPostResponse(HttpStatusCode.BadRequest, "增删民宿权限失败！");
                        }
                    }
                }
                catch (Exception ex)
                {
                    return new HttpPostResponse(HttpStatusCode.InternalServerError, "增删民宿权限失败！");
                }
            }
            else
            {
                return new HttpPostResponse(HttpStatusCode.Forbidden, "访问被拒绝！");
            }

        }

    }
}
